package fairygui.editor.publish
{
   import fairygui.editor.Consts;
   import fairygui.editor.animation.AniDef;
   import fairygui.editor.animation.AniTexture;
   import fairygui.editor.animation.DecodeSupport;
   import fairygui.editor.gui.EPackageItem;
   import fairygui.editor.gui.EUIProject;
   import fairygui.editor.pack.NodeRect;
   import fairygui.editor.pack.Page;
   import fairygui.editor.settings.AtlasSettings;
   import fairygui.editor.utils.BulkTasks;
   import fairygui.editor.utils.Callback;
   import fairygui.editor.utils.ImageTool;
   import fairygui.editor.utils.UtilsFile;
   import fairygui.editor.utils.UtilsStr;
   import fairygui.utils.GTimers;
   import flash.display.BitmapData;
   import flash.display.BitmapDataChannel;
   import flash.geom.Matrix;
   import flash.geom.Point;
   import flash.geom.Rectangle;
   import flash.utils.ByteArray;
   import mx.graphics.codec.JPEGEncoder;
   import mx.graphics.codec.PNGEncoder;
   
   public class CreateBins extends PublishStep
   {
       
      
      private var _loadTasks:BulkTasks;
      
      private var _compressTasks:BulkTasks;
      
      private var _atlasSprites:Array;
      
      private var _packing:Boolean;
      
      private var _packingIndex:int;
      
      private var _additionalAtlasIndex:int;
      
      private var _pages:Vector.<Page>;
      
      private var _atlasSettings:AtlasSettings;
      
      public function CreateBins()
      {
         super();
         this._atlasSettings = new AtlasSettings();
         this._atlasSprites = [];
         this._loadTasks = new BulkTasks(40);
         this._compressTasks = new BulkTasks(1);
      }
      
      override public function run() : void
      {
         if(publishData.atlases.length == 0)
         {
            this.allCompleted();
         }
         else
         {
            this._packingIndex = 0;
            this.doPack();
         }
      }
      
      private function allCompleted() : void
      {
         if(!publishData.exportDescOnly)
         {
            this._atlasSprites.sort();
            publishData.sprites = "//FairyGUI atlas sprites.\n" + this._atlasSprites.join("\n");
         }
         stepCallback.callOnSuccessImmediately();
      }
      
      private function packNext() : void
      {
         this._packingIndex++;
         if(this._packingIndex >= publishData.atlases.length)
         {
            this.allCompleted();
         }
         else
         {
            this.doPack();
         }
      }
      
      private function doPack() : void
      {
         var _loc2_:EPackageItem = null;
         var _loc5_:NodeRect = null;
         var _loc6_:AniDef = null;
         var _loc7_:int = 0;
         var _loc8_:AniTexture = null;
         var _loc9_:Rectangle = null;
         var _loc1_:AtlasItem = publishData.atlases[this._packingIndex];
         var _loc3_:Vector.<NodeRect> = new Vector.<NodeRect>();
         var _loc4_:int = 0;
         for each(_loc2_ in _loc1_.items)
         {
            if(_loc2_.type == EPackageItem.MOVIECLIP)
            {
               _loc6_ = AniDef(_loc2_.data);
               _loc7_ = 0;
               for each(_loc8_ in _loc6_.textureList)
               {
                  if(_loc8_.exportFrame != -1)
                  {
                     _loc9_ = _loc6_.frameList[_loc8_.exportFrame].rect;
                     if(_loc9_.width == 0 && _loc9_.height == 0)
                     {
                        continue;
                     }
                     _loc5_ = new NodeRect();
                     _loc5_.id = _loc4_ * 10000 + _loc7_;
                     _loc5_.width = _loc9_.width;
                     _loc5_.height = _loc9_.height;
                     _loc3_.push(_loc5_);
                  }
                  _loc7_++;
               }
               if(!_loc6_.ready && !_loc6_.queued && !publishData.exportDescOnly)
               {
                  DecodeSupport.inst.add(_loc6_);
               }
            }
            else
            {
               if(_loc2_.width > 0 && _loc2_.height > 0)
               {
                  _loc5_ = new NodeRect();
                  _loc5_.id = _loc4_ * 10000;
                  _loc5_.width = _loc2_.width;
                  _loc5_.height = _loc2_.height;
                  _loc3_.push(_loc5_);
               }
               if(!publishData.exportDescOnly)
               {
                  this._loadTasks.addTask(this.doLoad,_loc2_);
               }
            }
            _loc4_++;
         }
         if(!publishData.exportDescOnly)
         {
            this._loadTasks.addTask(this.doLoad2);
            this._loadTasks.start(this.onLoadCompleted);
         }
         this._packing = true;
         if(_loc1_.index == -1)
         {
            this._atlasSettings.copyFrom(publishData.pkg.publishSettings.atlasList[0]);
            if(_loc1_.items[0].imageSetting.atlas == "alone_npot")
            {
               this._atlasSettings.pot = false;
            }
            else
            {
               this._atlasSettings.pot = true;
            }
         }
         else
         {
            this._atlasSettings.copyFrom(publishData.pkg.publishSettings.atlasList[_loc1_.index]);
         }
         publishData._project.editorWindow.binPackManager.pack(_loc3_,this._atlasSettings,this.onPackCompleted);
      }
      
      private function onPackCompleted(param1:Vector.<Page>) : void
      {
         this._packing = false;
         this._pages = param1;
         if(param1 == null || param1.length > 1 && !this._atlasSettings.multiPage)
         {
            this._loadTasks.clear();
            stepCallback.msgs.length = 0;
            stepCallback.addMsg(UtilsStr.formatString(Consts.g.text122,this._atlasSettings.maxWidth,this._atlasSettings.maxHeight));
            stepCallback.callOnFailImmediately();
            return;
         }
         if(!this._loadTasks.running)
         {
            this.createBin();
         }
      }
      
      private function onLoadCompleted() : void
      {
         if(!this._packing)
         {
            this.createBin();
         }
      }
      
      private function createBin() : void
      {
         var _loc2_:EPackageItem = null;
         var _loc3_:AtlasOutput = null;
         var _loc5_:int = 0;
         var _loc6_:BitmapData = null;
         var _loc7_:BitmapData = null;
         var _loc8_:BitmapData = null;
         var _loc9_:int = 0;
         var _loc10_:AniTexture = null;
         var _loc11_:NodeRect = null;
         var _loc14_:Page = null;
         if(this._pages.length == 0)
         {
            this.packNext();
            return;
         }
         var _loc1_:AtlasItem = publishData.atlases[this._packingIndex];
         var _loc4_:Matrix = new Matrix();
         var _loc12_:Boolean = _loc1_.alphaChannel && publishData.extractAlpha;
         if(publishData._project.type == EUIProject.TYPE_UNITY)
         {
            _loc1_.alphaChannel = true;
         }
         var _loc13_:int = 0;
         for each(_loc14_ in this._pages)
         {
            _loc3_ = new AtlasOutput();
            publishData.atlasOutput.push(_loc3_);
            _loc9_ = _loc1_.index;
            if(_loc13_ == 0)
            {
               _loc9_ = _loc1_.index;
               _loc3_.id = _loc1_.id;
               _loc3_.fileName = _loc1_.id + (!!_loc1_.alphaChannel?".png":".jpg");
            }
            else
            {
               _loc9_ = 100 + this._additionalAtlasIndex++;
               _loc3_.id = "atlas" + _loc9_;
               _loc3_.fileName = _loc1_.id + "_" + _loc13_ + (!!_loc1_.alphaChannel?".png":".jpg");
            }
            _loc3_.width = _loc14_.width;
            _loc3_.height = _loc14_.height;
            _loc13_++;
            if(!publishData.exportDescOnly)
            {
               if(_loc14_.outputRects.length == 1)
               {
                  _loc11_ = _loc14_.outputRects[0];
                  _loc2_ = _loc1_.items[0];
                  if(_loc1_.items.length == 1 && _loc2_.type == EPackageItem.IMAGE && _loc3_.width == _loc2_.width && _loc3_.height == _loc2_.height && (_loc2_.imageInfo.format == "png" || publishData._project.type != EUIProject.TYPE_UNITY) && !_loc12_)
                  {
                     _loc3_.data = UtilsFile.loadBytes(_loc2_.imageInfo.file);
                     this.addSprite(_loc2_.id,_loc1_.index,this._pages[0].outputRects[0],false);
                     continue;
                  }
               }
               _loc8_ = new BitmapData(_loc14_.width,_loc14_.height,true,0);
               for each(_loc11_ in _loc14_.outputRects)
               {
                  _loc2_ = _loc1_.items[int(_loc11_.id / 10000)];
                  if(_loc2_.type == EPackageItem.MOVIECLIP)
                  {
                     _loc10_ = AniDef(_loc2_.data).textureList[_loc11_.id % 10000];
                     if(_loc10_.bitmapData)
                     {
                        if(_loc11_.rotated)
                        {
                           _loc4_.identity();
                           _loc4_.rotate(-90 * Math.PI / 180);
                           _loc4_.translate(_loc11_.x,_loc11_.y + _loc11_.height);
                           _loc8_.draw(_loc10_.bitmapData,_loc4_);
                        }
                        else
                        {
                           _loc8_.copyPixels(_loc10_.bitmapData,new Rectangle(0,0,_loc11_.width,_loc11_.height),new Point(_loc11_.x,_loc11_.y));
                        }
                        this.addSprite(_loc2_.id + "_" + _loc10_.exportFrame,_loc9_,_loc11_,_loc11_.rotated);
                     }
                  }
                  else
                  {
                     _loc6_ = BitmapData(_loc2_.data);
                     if(_loc6_ != null)
                     {
                        if(_loc2_.imageInfo.targetQuality > _loc5_)
                        {
                           _loc5_ = _loc2_.imageInfo.targetQuality;
                        }
                        if(_loc11_.rotated)
                        {
                           _loc4_.identity();
                           _loc4_.rotate(-90 * Math.PI / 180);
                           _loc4_.translate(_loc11_.x,_loc11_.y + _loc11_.height);
                           _loc8_.draw(_loc6_,_loc4_);
                        }
                        else
                        {
                           _loc8_.copyPixels(_loc6_,new Rectangle(0,0,_loc11_.width,_loc11_.height),new Point(_loc11_.x,_loc11_.y));
                        }
                        this.addSprite(_loc2_.id,_loc9_,_loc11_,_loc11_.rotated);
                     }
                  }
               }
               if(_loc12_)
               {
                  _loc7_ = new BitmapData(_loc8_.width,_loc8_.height,false,0);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.ALPHA,BitmapDataChannel.RED);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.ALPHA,BitmapDataChannel.GREEN);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.ALPHA,BitmapDataChannel.BLUE);
                  _loc3_.alphaData = new PNGEncoder().encode(_loc7_);
                  _loc7_.dispose();
               }
               if(!_loc1_.alphaChannel || _loc12_)
               {
                  _loc7_ = new BitmapData(_loc8_.width,_loc8_.height,false,0);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.RED,BitmapDataChannel.RED);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.GREEN,BitmapDataChannel.GREEN);
                  _loc7_.copyChannel(_loc8_,_loc8_.rect,new Point(0,0),BitmapDataChannel.BLUE,BitmapDataChannel.BLUE);
                  _loc8_.dispose();
                  _loc8_ = _loc7_;
               }
               if(_loc1_.alphaChannel)
               {
                  if(this._atlasSettings.compression)
                  {
                     this._compressTasks.addTask(this.doCompress,[_loc3_,_loc8_]);
                  }
                  else
                  {
                     _loc3_.data = new PNGEncoder().encode(_loc8_);
                     _loc8_.dispose();
                  }
               }
               else
               {
                  if(_loc5_ == 0)
                  {
                     _loc5_ = publishData.pkg.jpegQuality;
                  }
                  if(_loc5_ == 0)
                  {
                     _loc5_ = 80;
                  }
                  _loc3_.data = new JPEGEncoder(_loc5_).encode(_loc8_);
                  _loc8_.dispose();
               }
            }
         }
         if(this._compressTasks.itemCount > 0)
         {
            this._compressTasks.start(this.packNext);
         }
         else
         {
            this.packNext();
         }
      }
      
      private function doCompress() : void
      {
         var ao:AtlasOutput = null;
         var callback:Callback = null;
         ao = AtlasOutput(this._compressTasks.taskData[0]);
         var binBmd:BitmapData = BitmapData(this._compressTasks.taskData[1]);
         callback = new Callback();
         callback.success = function():void
         {
            BitmapData(callback.result).dispose();
            ao.data = ByteArray(callback.result2);
            _compressTasks.finishItem();
         };
         callback.failed = function():void
         {
            stepCallback.msgs.length = 0;
            stepCallback.addMsgs(callback.msgs);
            _compressTasks.clear();
            stepCallback.callOnFailImmediately();
         };
         callback.param = ao;
         ImageTool.compressBitmapData(binBmd,callback);
      }
      
      private function addSprite(param1:String, param2:int, param3:NodeRect, param4:Boolean) : void
      {
         var _loc5_:String = param2 + " " + param3.x + " " + param3.y + " " + param3.width + " " + param3.height + " " + (!!param4?1:0);
         this._atlasSprites.push(param1 + " " + _loc5_);
         var _loc6_:EPackageItem = publishData._fontTextures[param1];
         if(_loc6_)
         {
            this._atlasSprites.push(_loc6_.id + " " + _loc5_);
         }
      }
      
      private function doLoad() : void
      {
         var _loc1_:EPackageItem = EPackageItem(this._loadTasks.taskData);
         publishData.pkg.getImage(_loc1_,this.__loaded);
      }
      
      private function __loaded(param1:Object) : void
      {
         this._loadTasks.finishItem();
      }
      
      private function doLoad2() : void
      {
         if(DecodeSupport.inst.busy)
         {
            GTimers.inst.callLater(this.doLoad2);
         }
         else
         {
            this._loadTasks.finishItem();
         }
      }
   }
}
